; nasm -f bin _3.asm -o _3.bin
; qemu-img create _3.img 10m
; dd if=_3.bin of=_3.img bs=512 count=1 seek=0 conv=notrunc
; qemu-system-i386 -hda _3.img -serial null -parallel stdio

; qemu-system-i386 _3.bin
 

[bits 16]
org 0x7c00

xor ax, ax
mov ds, ax
mov ss, ax
mov sp, 0x7c00

global _start

_start:
    xor dx, dx
    call init_set_cursor_pos
    call input
    jmp $ ; 死循环

init_set_cursor_pos: ; 初始化光标位置
    mov ah, 0x2
    mov bh, 0x0
    mov dh, 0x0
    mov dl, 0x0
    int 0x10
    ret
input: ; 从缓冲区读取一个字符
    mov ah, 0x00
    int 0x16
    mov ah, 0x01
    cmp al, 'w'
    je up
    cmp al, 's'
    je down
    cmp al, 'a'
    je left
    cmp al, 'd'
    je right
    jmp input
    ret

up:
    mov ah, 03h   ; 获取光标位置和形状	AH=03H	BX=页码	AX=0，CH=行扫描开始，CL=行扫描结束，DH=行，DL=列
    int 10h
    dec dh
    mov ah, 02h  ; 设置光标位置	AH=02H	BH=页码，DH=行，DL=列
    int 10h 
    mov dx, 0x01
    call output
    ret

down:
    mov ah, 03h   ; 获取光标位置和形状	AH=03H	BX=页码	AX=0，CH=行扫描开始，CL=行扫描结束，DH=行，DL=列
    int 10h
    inc dh
    mov ah, 02h  ; 设置光标位置	AH=02H	BH=页码，DH=行，DL=列
    int 10h 
    mov dx, 0x02
    call output
    ret

left:
    mov ah, 03h   ; 获取光标位置和形状	AH=03H	BX=页码	AX=0，CH=行扫描开始，CL=行扫描结束，DH=行，DL=列
    int 10h
    dec dl
    mov ah, 02h  ; 设置光标位置	AH=02H	BH=页码，DH=行，DL=列
    int 10h 
    mov dx, 0x03
    call output
    ret

right:
    mov ah, 03h   ; 获取光标位置和形状	AH=03H	BX=页码	AX=0，CH=行扫描开始，CL=行扫描结束，DH=行，DL=列
    int 10h
    inc dl
    mov ah, 02h  ; 设置光标位置	AH=02H	BH=页码，DH=行，DL=列
    int 10h
    mov dx, 0x04
    call output 
    ret

output:
    mov ah, 10h  
    int 16h
    mov ah, 0x01
    mov ah, 9h   ;  在当前光标位置写字符和属性	AH=09H	AL=字符，BH=页码，BL=颜色，CX=多次打印字符
    mov bh, 0x00
    mov bl, 0xed ;  颜色
    mov cx, 0x01
    int 0x10
    call input
    ret

times 510-($-$$) db 0
dw 0xaa55
